import 'dart:typed_data';

import 'package:bluetooth_protocols_plugin/library.dart';

import '../../../tools/bit_utils.dart';
import '../../../tools/utils.dart';

/*
  // 电池组信息
  typedef struct{        //16 bytes
      VX_SINGLE_BATTERY_INFO battery[2];//单个电池信息
  }VX_BATTERY_PACK_INFO;

  // 其中单个电池信息 VX_SINGLE_BATTERY_INFO 定义如下
  typedef ARM_PACKED struct{        //8 bytes
      //实时数据 8 bytes
      uint16_t voltage;               //电压         单位 0.01V（来自驱动板）
      int16_t charge_current;         //充电电流         单位 0.01A（来自驱动板）
      int16_t discharge_current;      //放电电流         单位 0.01A（来自驱动板）

      //6个状态位
      uint16_t state_detected       : 1; //0 电池信号无效   1 电池信号有效  （来自驱动板，对于有通讯的电池即为电池通讯状态）
      uint16_t state_enable         : 1; //0 电池未开启     1 电池开启      （来自驱动板）
      uint16_t state_charge         : 1; //0 未充电状态     1 充电状态      （来自驱动板）
      uint16_t state_reserve        : 3; //保留

      //10个故障或警告位
      uint16_t error_logic             : 1; //0 信号逻辑正常   1 信号逻辑错误（电池信号存在，但电压低于一定值 或者 电池信号不存在，但电压高于一定值）
      uint16_t error_signal            : 1; //0 电池未报错     1 电池报错（只有不含通讯的电池有此故障）
      uint16_t error_voltage_sensor    : 1; //0 电压传感器正常 1 电压传感器故障（来自驱动板）
      uint16_t error_current_sensor    : 1; //0 电流传感器正常 1 电流传感器故障（来自驱动板）
      uint16_t error_cannot_charge     : 1; //0 未发现无法充电 1 电池无法充电故障（来自驱动板）
      uint16_t battery_warning         : 1; //BMS 有报警信息（来自BMS）
      uint16_t battery_protect         : 1; //BMS 触发保护（来自BMS）
      uint16_t battery_error           : 1; //BMS 有故障信息（来自BMS）
      uint16_t error_reserve           : 2; //保留
  }GNUC_PACKED VX_SINGLE_BATTERY_INFO;
*/

// rs_jet 实时电池信息
class RsJetRealtimeBatteryInfo
    extends LorinRealtimeBatteryInfo<RsJetBatteryPackInfo> {
  // 电池组信息
  final List<RsJetBatteryPackInfo> _batteryPacks = [];

  RsJetRealtimeBatteryInfo.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
    if (bytes.length < minLength) {
      throw ArgumentError('Bytes length is less than minimum length.');
    }

    final singleLen = minLength ~/ 2; // 每个电池包的长度
    for (int i = 0; i < batteryPacksCount; i++) {
      final offset = i * singleLen;
      final packBytes = bytes.sublist(offset, offset + singleLen);
      _batteryPacks.add(RsJetBatteryPackInfo.fromBytes(packBytes));
    }
  }

  @override
  List<RsJetBatteryPackInfo> get batteryPacks => _batteryPacks;

  @override
  int dataIntValue() =>
      _batteryPacks.fold(0, (total, pack) => total + pack.dataIntValue());

  @override
  int dataLength() =>
      _batteryPacks.fold(0, (total, pack) => total + pack.dataLength());

  @override
  Uint8List toBytes() {
    final result = Uint8List(dataLength());
    int offset = 0;

    for (final pack in _batteryPacks) {
      final packBytes = pack.toBytes();
      result.setRange(offset, offset + packBytes.length, packBytes);
      offset += packBytes.length;
    }

    return result;
  }

  @override
  Map<String, dynamic> toMap() {
    return {
      'version': '$runtimeType',
      'batteryPacks': _batteryPacks.map((pack) => pack.toMap()).toList(),
      'dataLength': dataLength(),
      'minLength': minLength,
      'bytes': Utils.uint8List2HexString(toBytes()),
    };
  }
}

// rs_jet 电池组信息
class RsJetBatteryPackInfo extends LorinBatteryPackInfoBase {
  int chargeCurrent = 0; // 充电电流 单位 0.1A
  int dischargeCurrent = 0; // 放电电流 单位 0.1A
  bool errorCannotCharge = false; // 不能充电错误
  bool batteryWarning = false; // 电池警告
  bool batteryProtection = false; // 电池保护
  bool batteryError = false;

  RsJetBatteryPackInfo.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
    int offset = 0;
    var byteData = ByteData.sublistView(bytes);
    voltage = byteData.getUint16(offset, Endian.big);
    chargeCurrent = byteData.getInt16(offset + 2, Endian.big);
    dischargeCurrent = byteData.getInt16(offset + 4, Endian.big);

    int stateBits = byteData.getUint16(offset + 6, Endian.big);
    stateDetected = BitUtils.isBitOne(stateBits, 0);
    stateEnable = BitUtils.isBitOne(stateBits, 1);
    stateCharge = BitUtils.isBitOne(stateBits, 2);
    // state_reserve        : 3; //保留
    errorLogic = BitUtils.isBitOne(stateBits, 6);
    errorSignal = BitUtils.isBitOne(stateBits, 7);
    errorVoltageSensor = BitUtils.isBitOne(stateBits, 8);
    errorCurrentSensor = BitUtils.isBitOne(stateBits, 9);
    errorCannotCharge = BitUtils.isBitOne(stateBits, 10);
    batteryWarning = BitUtils.isBitOne(stateBits, 11);
    batteryProtection = BitUtils.isBitOne(stateBits, 12);
    batteryError = BitUtils.isBitOne(stateBits, 13);
  }

  @override
  Map<String, dynamic> toMap() {
    var map = super.toMap(); // 先获取父类的 Map
    map['version'] = 'RsJetBatteryPackInfo';
    map['chargeCurrent'] = chargeCurrent;
    map['dischargeCurrent'] = dischargeCurrent;
    map['errorCannotCharge'] = errorCannotCharge;
    map['batteryWarning'] = batteryWarning;
    map['batteryProtection'] = batteryProtection;
    map['batteryError'] = batteryError;
    return map;
  }

  @override
  Uint8List toBytes() {
    var byteData = ByteData(bytesLength);

    // 实时数据
    byteData.setUint16(0, voltage, Endian.big);
    byteData.setInt16(2, chargeCurrent, Endian.big);
    byteData.setInt16(4, dischargeCurrent, Endian.big);

    // 状态位
    int stateBits = 0;
    stateBits |= BitUtils.setBit(0, stateDetected);
    stateBits |= BitUtils.setBit(1, stateEnable);
    stateBits |= BitUtils.setBit(2, stateCharge);
    // 故障或警告位
    stateBits |= BitUtils.setBit(6, errorLogic);
    stateBits |= BitUtils.setBit(7, errorSignal);
    stateBits |= BitUtils.setBit(8, errorVoltageSensor);
    stateBits |= BitUtils.setBit(9, errorCurrentSensor);
    stateBits |= BitUtils.setBit(10, errorCannotCharge);
    stateBits |= BitUtils.setBit(11, batteryWarning);
    stateBits |= BitUtils.setBit(12, batteryProtection);
    stateBits |= BitUtils.setBit(13, batteryError);

    byteData.setUint16(6, stateBits, Endian.big);

    return byteData.buffer.asUint8List();
  }

  @override
  int get bytesLength => 8;

  @override
  int dataIntValue() {
    return voltage +
        chargeCurrent +
        dischargeCurrent +
        (stateDetected ? 1 : 0) +
        (stateEnable ? 1 : 0) +
        (stateCharge ? 1 : 0) +
        (errorLogic ? 1 : 0) +
        (errorSignal ? 1 : 0) +
        (errorVoltageSensor ? 1 : 0) +
        (errorCurrentSensor ? 1 : 0) +
        (errorCannotCharge ? 1 : 0) +
        (batteryWarning ? 1 : 0) +
        (batteryProtection ? 1 : 0) +
        (batteryError ? 1 : 0);
  }

  @override
  int dataLength() {
    return bytesLength;
  }
}
